﻿using System.Collections.Generic;
using System.Linq;
using Dorm.Helpers;
using Dorm.QueryObject;
using Dorm.Testes;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Dorm.Tests
{
    [TestClass]
    public class Query_Tests
    {
        private Database db = new Database();

        //[ClassInitialize]
        //public static void Create_Base(TestContext tc) { InsertDeleteTests.GenerateData(); }

        [TestMethod]
        public void Can_Get_Property_Names()
        {
            string name = LambdaParser.GetFieldName<Person>(x => x.Name);
            string permissions = LambdaParser.GetFieldName<Person>(x => x.Permissions);
            string homeAddress = LambdaParser.GetFieldName<Person>(x => x.HomeAddress);
            string homeCity = LambdaParser.GetFieldName<Person>(x => x.HomeAddress.City);
            
            Assert.AreEqual(name, "Name");
            Assert.AreEqual(permissions, "Permissions");
            Assert.AreEqual(homeAddress, "HomeAddress");
            Assert.AreEqual(homeCity, "HomeAddress.City");
        }

        [TestMethod]
        public void Can_Query_All_Users()
        {
            var allUsers = db.List(new Query<Person>());
            Assert.AreEqual(11, allUsers.Count);
        }

        [TestMethod]
        public void Can_Query_A_Page_Of_Users()
        {
            long totalRecords;
            var firstPageUsers = db.ListPage(new Query<Person>(), 1, 10, out totalRecords);
            Assert.AreEqual(10, firstPageUsers.Count);
            Assert.AreEqual(11, totalRecords);
        }

        [TestMethod]
        public void Can_Filter_Scalar_Property()
        {
            var query = new Query<Person>().Filter(p => p.Name).Contains("1");
            var firstUser = db.First(query);
            Assert.IsTrue(firstUser.Name.StartsWith("User 1"));
        }

        [TestMethod]
        public void Can_Filter_Component_Property()
        {
            var query = new Query<Person>().Filter(p => p.HomeAddress.City).Contains("B");
            var firstUser = db.First(query);
            Assert.IsTrue(firstUser.Name.StartsWith("User 1"));
        }

        [TestMethod]
        public void Can_Filter_Reference_Property()
        {
            var query = new Query<Person>().Filter(p => p.Type.Name).StartsWith("Ex");
            var firstUser = db.First(query);
            Assert.IsTrue(firstUser.Name.StartsWith("User 2"));
        }

        [TestMethod]
        public void Can_Filter_HasMany_Property()
        {
            var query = new Query<Person>()
                .Filter(p => p.Name).StartsWith("User")
                .Filter(p => p.Permissions).IsNotNull();
            
            var users = db.List(query);

            Assert.AreEqual(3, users.Count());
        }

        [TestMethod]
        public void Can_Filter_Children_HasManyToMany()
        {
            var profileList = db.List(new Query<Profile>().Top(2));

            var query = new Query<Person>()
                .Filter(p => p.Profiles).In(profileList);
            
            var users = db.List(query);

            Assert.AreEqual(3, users.Count());
        }

        //[ClassCleanup]
        //public static void Clean_Base() { InsertDeleteTests.CleanData(); }
    }
}
